package com.example.readfile

import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.cloudplay.messagesdk.MessageSDK
import com.cloudplay.messagesdk.listener.MessageHandler
import com.google.gson.Gson
import com.haima.agentpartner.DeviceInfo
import com.haima.agentpartner.HaimaMiddlewareBean
import com.haima.agentpartner.HaimaMiddlewareResponse
import com.haima.agentpartner.IMiddlewareRequest
import fuck.hookwzry.qq.FileRead
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONException
import org.jsoup.Connection
import org.jsoup.Jsoup
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit

const val AUTH_BASEURL = "http://47.98.46.249/cat/v1"
private const val TAG = "AuthorTool"

/**
 * 上号授权方式
 */
enum class AuthLoginType {
    WZ, // 王者荣耀
    HP, // 和平精英
    HY; // 火影忍者
}

class DebugActivity : ComponentActivity() {

    /**<定时器，检查QQ文件是否存在>**/
    private var executorService: ScheduledExecutorService? = null
    private var isOnQQ: Boolean = false
    private var imeitView: TextView? = null
    private var guidtView: TextView? = null
    private var tkkView: TextView? = null
    private var resultView: TextView? = null
    private var a_main_tv_result: TextView? = null
    private var a_main_et_msg_content: EditText? = null
    private var a_main_device_result: TextView? = null

    @SuppressLint("UseSwitchCompatOrMaterialCode")
    private var switch: Switch? = null

    /**<授权方式>**/
    private var authType: AuthLoginType? = null

    private var mIsBound = false
    private var middlewareRequest: IMiddlewareRequest? = null

    /**
     * bindService连接成功后
     */
    private val connection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            Log.d(TAG, "连接中..")
            try {
                middlewareRequest = IMiddlewareRequest.Stub.asInterface(service)
                Log.d(TAG, "连接 Middleware 服务，开始监听请求")
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
        }

        override fun onServiceDisconnected(name: ComponentName) {
            Log.d(TAG, "断开连接..")
            middlewareRequest = null
        }
    }

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_debug)

        // 消息SDK初始化
        initMessageSDK()
        // 绑定服务
        bindBoundService()
        // 设置视图
        setupViews()
        // 设置点击
        setupButtonActions()
    }

    /**
     * 创建定时服务
     */
    @OptIn(DelicateCoroutinesApi::class)
    @SuppressLint("SetTextI18n")
    private fun createExecutorService() {
        // 创建一个单线程的ScheduledExecutorService
        executorService = Executors.newSingleThreadScheduledExecutor()
        // 每秒执行一次任务
        executorService?.scheduleAtFixedRate({
            // 这里执行你的任务，注意这不是在主线程执行
            if (!isOnQQ) {
                return@scheduleAtFixedRate
            }
            Log.d(TAG, "执行轮询任务")
            resultView?.text = "执行轮询任务中..."

            // 异步执行耗时操作
            GlobalScope.launch(Dispatchers.IO) {
                // 检查文件夹权限并申请权限
                val hasPermissions = FileRead.hasReadAndWritePermissions(this@DebugActivity, true)
                if (!hasPermissions) {
                    Log.d(TAG, "没有权限，去申请权限")
                    resultView?.text = "没有权限，去申请权限"
                    getRootPermission(false)
                    return@launch
                }

                // 读取IMEI
                val imei = FileRead.readQimei(this@DebugActivity, false)
                withContext(Dispatchers.Main) {
                    imeitView?.text = if (imei.isNullOrEmpty()) "未查询到imei文件：$imei" else imei
                }

                // 读取Guide
                val guide = FileRead.readGuid(this@DebugActivity, false)
                withContext(Dispatchers.Main) {
                    guidtView?.text =
                        if (guide.isNullOrEmpty()) "未查询到guide文件: $guide" else guide
                }

                // 获取Ticket
                val ticket = FileRead.getTk(this@DebugActivity, guide, false)
                withContext(Dispatchers.Main) {
                    tkkView?.text =
                        if (ticket.isNullOrEmpty()) "未查询到ticket文件：$ticket" else ticket.toString()
                }

                // 马上停止查询
                isOnQQ = false

                // 登录成功了
                // 直接去授权[默认授权王者]
                withContext(Dispatchers.Main) {
                    handleAuthorization(1104466820L)
                }
            }
        }, 0, 1, TimeUnit.SECONDS)
    }

    /**
     * 绑定服务
     */
    private fun bindBoundService() {
        try {
            mIsBound = bindService()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 设置视图
     */
    private fun setupViews() {
        // 获取Switch控件
        switch = findViewById(R.id.switch1)
        switch?.isChecked = FileRead.useLocalFile
        // 设置开关状态变化的监听器
        switch?.setOnCheckedChangeListener { _, isChecked ->
            FileRead.useLocalFile = isChecked
        }

        // 设置View
        imeitView = findViewById(R.id.imeiResult)
        guidtView = findViewById(R.id.guidResult)
        tkkView = findViewById(R.id.tkkResult)
        resultView = findViewById(R.id.scanResult)
        a_main_tv_result = findViewById(R.id.a_main_tv_result)
        a_main_et_msg_content = findViewById(R.id.a_main_et_msg_content)
        a_main_device_result = findViewById(R.id.deviceInfoResult)
    }

    /**
     * 获取文件夹的root权限
     */
    private fun getRootPermission(needToast: Boolean) {
        val result = FileRead.getRootPermission(this, needToast)
        Log.d(TAG, "Root权限修改：$result")
        sendMessage("Root权限修改：$result")
    }

    /**
     * 测试模式
     * 设置按钮点击
     */
    @SuppressLint("SetTextI18n")
    private fun setupButtonActions() {
        // 打开QQ【打开云游戏->云游戏授权QQ登录，登陆成功后再进行授权】
        val btnSubmit = findViewById<Button>(R.id.btnSubmit)
        btnSubmit.setOnClickListener {
            openMobileQQ()
        }

        // 设置文件夹root权限
        val btnChmod = findViewById<Button>(R.id.btnChomd)
        btnChmod.setOnClickListener {
            getRootPermission(true)
        }

        // 检测文件夹读写权限
        val btnCheckChmod = findViewById<Button>(R.id.btnCheckChomd)
        btnCheckChmod.setOnClickListener {
            FileRead.hasReadAndWritePermissions(this, true)
        }

        // 检测imei
        val readilyImei = findViewById<Button>(R.id.btnReadFile_IMEI)
        readilyImei.setOnClickListener {
            val imei = FileRead.readQimei(this, true)
            imeitView?.text = imei
        }

        // 读取guide
        val readilyGuide = findViewById<Button>(R.id.btnReadFile_GUIDE)
        readilyGuide.setOnClickListener {
            val guide = FileRead.readGuid(this, true)
            guidtView?.text = guide
        }

        // 读取tkk
        val readilyTak = findViewById<Button>(R.id.btnReadFile_TKK)
        readilyTak.setOnClickListener {
            val guide = FileRead.readGuid(this, true)
            val ticket = FileRead.getTk(this, guide, true)
            tkkView?.text = ticket.toString()
        }

        // 授权王者
        val btnAuth = findViewById<Button>(R.id.btnAuth)
        btnAuth.setOnClickListener {
            authType = AuthLoginType.WZ
            handleAuthorization(1104466820L)
        }

        // 授权吃鸡
        val btnAuthChiji = findViewById<Button>(R.id.btnAuthChiji)
        btnAuthChiji.setOnClickListener {
            authType = AuthLoginType.HP
            handleAuthorization(1106467070L)
        }

        // 发送消息
        val aMainBtnSendTxt = findViewById<Button>(R.id.a_main_btn_send_txt)
        aMainBtnSendTxt.setOnClickListener {
            val msgContent = a_main_et_msg_content?.getText().toString()
            sendMessage(msgContent)
        }

        // 获取设备信息并上传
        val btnGetDeviceInfo = findViewById<Button>(R.id.btnGetDeviceInfo)
        btnGetDeviceInfo.setOnClickListener {
            getDeviceInfo()
        }

    }

    /**
     * 打开QQ
     */
    private fun openMobileQQ() {
        try {
            isOnQQ = true
            val uri = Uri.parse("mqqwpa://im/login?style=4")
            val intent = Intent(Intent.ACTION_VIEW, uri)
            startActivity(intent)
        } catch (e: ActivityNotFoundException) {
            isOnQQ = false
            // QQ客户端没有安装
            Toast.makeText(this, "未安装QQ或找不到QQ", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 中间件与客户端交互的SDK初始化
     */
    @SuppressLint("SetTextI18n")
    private fun initMessageSDK() {
        MessageSDK.getInstance().setDebug(true)
        MessageSDK.getInstance().init(this, packageName)

        Log.d(TAG, "isRunningCloud = " + MessageSDK.getInstance().isRunningCloud)

        // 监控消息
        val messageHandler: MessageHandler = object : MessageHandler {

            // 收到二进制消息
            override fun onBinaryMessage(bytes: ByteArray) {
                Log.d(TAG, "onBinaryMessage:" + String(bytes))
                a_main_tv_result?.text = "二进制消息:" + String(bytes)
            }

            // 收到普通text消息
            override fun onTextMessage(payload: String) {
                Log.d(TAG, "onTextMessage:$payload")
                a_main_tv_result?.text = "普通消息:$payload"

                // 设备信息
                try {
                    val gson = Gson()
                    val device: DeviceInfo = gson.fromJson(payload, DeviceInfo::class.java)

                    Log.d(TAG, "onTextMessage model:${device.model}")
                    Log.d(TAG, "onTextMessage brand:${device.brand}")

                    // 设置设备信息
                    setDeviceInfo(device.model, device.brand)

                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
        }
        MessageSDK.getInstance().setMessageHandler(messageHandler)
    }

    /**
     * 注销SDK
     */
    private fun unInitMessageSDK() {
        MessageSDK.getInstance().stop()
    }

    /**
     * 发送消息
     *
     * @param msgContent 消息内容
     */
    private fun sendMessage(msgContent: String) {
        val mId = MessageSDK.getInstance().sendMessage(msgContent) { success, messageId ->
            val sendResult = "发送文本消息: msg:$msgContent, mId:$messageId,result:$success"
            Log.d(TAG, sendResult)
            a_main_tv_result?.text = sendResult
        }
        Log.d(TAG, "发送消息后的 messageId:$mId")
    }

    /**
     * 授权结果
     * 先要检测登录态文件是否存在
     */
    @SuppressLint("SetTextI18n")
    private fun handleAuthorization(appId: Long) {
        Thread {
            try {
                if (imeitView?.text.isNullOrEmpty() || guidtView?.text.isNullOrEmpty() || tkkView?.text.isNullOrEmpty()) {
                    return@Thread
                }
                try {
                    // 将JSON字符串解析为JSONObject
                    val jsonObject: JSONObject = JSON.parseObject(
                        tkkView?.text.toString()
                    )
                    processAuthorization(
                        imeitView?.text.toString(),
                        guidtView?.text.toString(),
                        jsonObject,
                        appId
                    )
                } catch (e: Exception) {
                    println("Error parsing JSON: ${e.message}")
                }

            } catch (e: Exception) {
                e.printStackTrace()
            }
        }.start()
    }

    /**
     * 开始授权
     */
    private fun processAuthorization(
        qimei: String,
        guid: String,
        ticket: JSONObject,
        appId: Long
    ) {
        val spreadData = JSON.parseObject(qimei).getJSONObject("spreadData")
        val data = spreadData.getJSONObject(ArrayList(spreadData.keys)[0])
        val jsonObject = JSONObject().apply {
            put("appid", appId)
            put("model", Build.MODEL)
            put("brand", Build.BRAND)

            put("imei", data.getString("aid"))
            put("androidId", data.getString("aid"))
            put("qimei", data.getString("q16"))
            put("guid", guid)

            put("qq", ticket.getString("qq"))
            put("ticket", ticket)

            // 王者多一个参数
            if (authType == AuthLoginType.WZ) {
                put("key", "zerPob3P12IPjf5lBWKtVffu")
            }
        }
        postAuthorization(jsonObject)
    }

    /**
     * 发送授权请求
     */
    @SuppressLint("SetTextI18n")
    private fun postAuthorization(auth: JSONObject) {
        try {
            val response = Jsoup.connect("$AUTH_BASEURL/mobile/saveDeviceInfo")
                .timeout(20000)
                .ignoreContentType(true)
                .ignoreHttpErrors(true)
                .header("content-type", "application/json;charset=UTF-8")
                .method(Connection.Method.POST)
                .requestBody(auth.toJSONString())
                .execute()

            val body = response.body()
            Log.i(TAG, "body = $body")

            val `object` = JSON.parseObject(body)
            runOnUiThread {
                val desc = `object`.getString("desc")
                resultView?.text = "授权结果：$desc"

                // 发送消息
                sendMessage(desc)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 发送保存设备信息请求
     */
    @SuppressLint("SetTextI18n")
    private fun postSaveDevice(info: DeviceInfo) {
        try {
            val content = Gson().toJson(info)
            Log.i(TAG, "content = $content")

            val jsonObject = JSONObject().apply {
                put("param", content)
            }

            val response = Jsoup.connect("$AUTH_BASEURL/mer-api/mobile/saveDeviceInfo")
                .timeout(20000)
                .ignoreContentType(true)
                .ignoreHttpErrors(true)
                .header("content-type", "application/json;charset=UTF-8")
                .method(Connection.Method.POST)
                .requestBody(jsonObject.toJSONString())
                .execute()

            val body = response.body()
            Log.i(TAG, "body = $body")

            val `object` = JSON.parseObject(body)
            runOnUiThread {
                a_main_device_result?.text = "上传设备结果：$body"

                val desc = `object`.getString("msg")
                if (!desc.isNullOrEmpty()) {
                    // 发送消息
                    sendMessage(desc)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 通过commonFunction
     * 设置设备信息
     */
    @SuppressLint("SetTextI18n")
    @Throws(RemoteException::class)
    private fun setDeviceInfo(model: String, brand: String) {
        //1.构造需要设置的设备信息参数
        val deviceInfo = DeviceInfo()
        deviceInfo.model = model
        deviceInfo.brand = brand

        //2. 构造调用commonFunction的请求参数
        val haimaMiddlewareBean = HaimaMiddlewareBean()
        haimaMiddlewareBean.methodName = "setDeviceInfo"
        haimaMiddlewareBean.info = deviceInfo

        //3. 将请求参数转为json字符串并通过aidl调用
        val gson = Gson()
        val result = middlewareRequest?.commonFunction(gson.toJson(haimaMiddlewareBean))
        //4.处理返回的结果
        if (result != null) {
            val response: HaimaMiddlewareResponse = gson.fromJson<HaimaMiddlewareResponse>(
                result,
                HaimaMiddlewareResponse::class.java
            )
            // 0表示失败，为-1则表示设置设备信息出错
            val success = response.result == 1
            Log.i(TAG, "设置设备信息success： $success")
            if (success) {
                // 成功了，应该告诉客户端
                sendMessage("设置设备信息成功：model：$model, brand：$brand")

                a_main_tv_result?.text = "设置设备信息成功：model：$model, brand：$brand"

                // 创建一个定时服务
                createExecutorService()

                // 自动启动QQ
                openMobileQQ()
            } else {
                sendMessage("设置设备信息失败：${response.errorMsg}")
            }
        } else {
            sendMessage("设置设备信息失败")
        }
    }

    /**
     * 通过commonFunction获取设备信息
     */
    @SuppressLint("SetTextI18n")
    @Throws(RemoteException::class, JSONException::class)
    private fun getDeviceInfo() {
        val isInCloud = MessageSDK.getInstance().isRunningCloud
        if (isInCloud) {
            val haimaMiddlewareBean = HaimaMiddlewareBean()
            haimaMiddlewareBean.methodName = "getDeviceInfo"
            val gson = Gson()
            //2.调用commonFunction获取设备信息
            val result = middlewareRequest?.commonFunction(gson.toJson(haimaMiddlewareBean))
            if (result != null) {
                val response = gson.fromJson(
                    result,
                    HaimaMiddlewareResponse::class.java
                )
                //若result==1则说明获取设备信息成功
                if (response.result == 1) {
                    //直接将successMsg反序列化为DeviceInfo对象即可
                    val deviceInfo = gson.fromJson(
                        response.successMsg,
                        DeviceInfo::class.java
                    )
                    Log.d(TAG, "deviceInfo=$deviceInfo")
                    a_main_device_result?.text = "deviceInfo=$deviceInfo"
                    Thread {
                        try {
                            postSaveDevice(deviceInfo)
                        } catch (e: Exception) {
                            Log.e(TAG, e.toString())
                        }
                    }.start()
                }
            }
        } else {
            val info = DeviceInfo()
            info.gameName = "王者荣耀"
            info.androidId = "fa3c4df7b11b4ed5"
            info.baseBand = "6FBQ9WIBB1JEJD5G4P"
            info.board = "full_k50v5_64"
            info.bootId = "8e8c9bac-57f4-4202-a512-b4659f352304"
            info.bootLoader = "unknown"
            info.brand = "OnePlus"
            info.buildDescription = "description-841006127"
            info.buildHost = "a03405d2-7535-48d9-b833-8f74037f82c3"
            info.buildId = "HFN2Z0V5KQ"

            Thread {
                try {
                    postSaveDevice(info)
                } catch (e: Exception) {
                    Log.e(TAG, e.toString())
                }
            }.start()
        }
    }

    /**
     * 绑定服务
     *
     * @return service
     */
    private fun bindService(): Boolean {
        val intent = Intent()
        intent.setAction("com.android.agent.partner.MIDDLEWARE_REQUEST")
        intent.setPackage("com.android.agent.partner")
        return bindService(intent, connection, BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mIsBound) {
            unbindService(connection)
            mIsBound = false
        }

        // 注销SDK
        unInitMessageSDK()

        executorService?.shutdownNow()
        println("定时器已销毁")
    }


    override fun onResume() {
        super.onResume()
        isOnQQ = false
    }
}
